package com.example.screenshot_service

import android.accessibilityservice.AccessibilityService
import android.accessibilityservice.AccessibilityServiceInfo
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.PixelFormat
import android.hardware.display.DisplayManager
import android.hardware.display.VirtualDisplay
import android.media.Image
import android.media.ImageReader
import android.media.projection.MediaProjection
import android.media.projection.MediaProjectionManager
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.provider.Settings
import android.util.DisplayMetrics
import android.util.Log
import android.view.WindowManager
import android.view.accessibility.AccessibilityEvent
import androidx.annotation.RequiresApi
import java.io.File
import java.io.FileOutputStream
import java.nio.ByteBuffer
import java.util.concurrent.CountDownLatch

/**
 * 无障碍服务类，用于获取屏幕截图
 * 通过MediaProjection API实现截图功能
 */
class ScreenshotService : AccessibilityService() {

    companion object {
        private const val TAG = "ScreenshotService"
        private var instance: ScreenshotService? = null
        private var mediaProjectionManager: MediaProjectionManager? = null
        private var mediaProjection: MediaProjection? = null
        private var resultCode: Int = 0
        private var resultData: Intent? = null
        private var screenshotCallback: ((String?) -> Unit)? = null
        private var densityDpi: Int = 0
        private var width: Int = 0
        private var height: Int = 0

        /**
         * 获取服务实例
         */
        fun getInstance(): ScreenshotService? {
            return instance
        }

        /**
         * 设置媒体投影数据
         */
        fun setProjectionData(resultCode: Int, resultData: Intent) {
            this.resultCode = resultCode
            this.resultData = resultData
        }

        /**
         * 检查无障碍服务是否已启用
         */
        fun isAccessibilityServiceEnabled(context: Context): Boolean {
            val enabledServices = Settings.Secure.getString(
                context.contentResolver,
                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
            ) ?: return false

            return enabledServices.contains(context.packageName + "/" + ScreenshotService::class.java.name)
        }
    }

    /**
     * 服务连接时调用
     */
    override fun onServiceConnected() {
        super.onServiceConnected()
        instance = this
        Log.d(TAG, "无障碍服务已连接")

        val info = AccessibilityServiceInfo()
        info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK
        info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC
        info.flags = AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS
        serviceInfo = info

        mediaProjectionManager = getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
        val metrics = DisplayMetrics()
        val windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            val bounds = windowManager.currentWindowMetrics.bounds
            width = bounds.width()
            height = bounds.height()
            densityDpi = resources.configuration.densityDpi
        } else {
            @Suppress("DEPRECATION")
            windowManager.defaultDisplay.getMetrics(metrics)
            width = metrics.widthPixels
            height = metrics.heightPixels
            densityDpi = metrics.densityDpi
        }
    }

    /**
     * 处理无障碍事件（本例中不需要处理）
     */
    override fun onAccessibilityEvent(event: AccessibilityEvent) {
        // 不需要处理无障碍事件，因为我们只需要使用服务进行截图
    }

    /**
     * 服务中断时调用
     */
    override fun onInterrupt() {
        Log.d(TAG, "无障碍服务被中断")
    }

    /**
     * 服务销毁时调用
     */
    override fun onDestroy() {
        super.onDestroy()
        instance = null
        Log.d(TAG, "无障碍服务被销毁")
    }

    /**
     * 获取屏幕截图
     * @param callback 回调函数，返回截图文件路径或null（如果失败）
     */
    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    fun takeScreenshot(callback: (String?) -> Unit) {
        if (resultCode == 0 || resultData == null) {
            Log.e(TAG, "没有媒体投影权限数据")
            callback(null)
            return
        }

        screenshotCallback = callback
        try {
            if (mediaProjection == null) {
                mediaProjection = mediaProjectionManager?.getMediaProjection(resultCode, resultData!!)
            }
            captureScreen()
        } catch (e: Exception) {
            Log.e(TAG, "截图出错: ${e.message}")
            callback(null)
        }
    }

    /**
     * 实际执行屏幕截图的方法
     */
    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    private fun captureScreen() {
        if (mediaProjection == null) {
            Log.e(TAG, "MediaProjection为空")
            screenshotCallback?.invoke(null)
            return
        }

        val imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 2)

        val virtualDisplay = mediaProjection!!.createVirtualDisplay(
            "ScreenCapture",
            width, height, densityDpi,
            DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
            imageReader.surface, null, null
        )

        // 等待图像可用
        val latch = CountDownLatch(1)
        val handler = Handler(Looper.getMainLooper())

        imageReader.setOnImageAvailableListener({ reader ->
            var image: Image? = null
            var bitmap: Bitmap? = null
            var fileOutput: FileOutputStream? = null

            try {
                image = reader.acquireLatestImage()
                if (image != null) {
                    val planes = image.planes
                    val buffer = planes[0].buffer
                    val pixelStride = planes[0].pixelStride
                    val rowStride = planes[0].rowStride
                    val rowPadding = rowStride - pixelStride * width

                    bitmap = Bitmap.createBitmap(
                        width + rowPadding / pixelStride,
                        height, Bitmap.Config.ARGB_8888
                    )
                    bitmap.copyPixelsFromBuffer(buffer)

                    // 保存到文件
                    val folder = File(filesDir, "screenshots")
                    if (!folder.exists()) {
                        folder.mkdirs()
                    }

                    val file = File(folder, "screenshot_${System.currentTimeMillis()}.png")
                    fileOutput = FileOutputStream(file)
                    bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutput)

                    handler.post {
                        Log.d(TAG, "截图成功：${file.absolutePath}")
                        screenshotCallback?.invoke(file.absolutePath)
                        screenshotCallback = null
                    }
                } else {
                    Log.e(TAG, "截图失败：无法获取图像")
                    handler.post {
                        screenshotCallback?.invoke(null)
                        screenshotCallback = null
                    }
                }
            } catch (e: Exception) {
                Log.e(TAG, "处理截图时出错: ${e.message}")
                handler.post {
                    screenshotCallback?.invoke(null)
                    screenshotCallback = null
                }
            } finally {
                fileOutput?.close()
                bitmap?.recycle()
                image?.close()
                virtualDisplay.release()
                latch.countDown()
            }
        }, handler)

        // 延迟一下确保图像已准备好，3秒后超时
        handler.postDelayed({
            if (latch.count > 0) {
                Log.e(TAG, "截图超时")
                latch.countDown()
                screenshotCallback?.invoke(null)
                screenshotCallback = null
            }
        }, 3000)
    }
} 